{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python is Dynamically(动态的)but Strongly typed（强类型）language"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "variable是一个int？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "variable = 8"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "variable"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "variable是一个str？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "variable=\"Hello ,I am William from LXOD\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Hello ,I am William from LXOD'"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "variable"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "思考：variable是否变更了类型？"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "注意！variable并没有变更类型！！！"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "因为variable并不是一个对象（object），而是一个贴在对象上面的纸条（name）！"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "variable = 8其实是我们创建了一个integer object(对象，类型为int)，并且将3这个值放到这个对象里面，并且跟这个对象起了个名字（binding）,名字叫做variable\n",
    "variable=\"Hello ,I am William from LXOD\"，其实是我们再次创建了一个string object（对象，类型为str），并且将\"Hello ,I am William from LXOD\"这么一长串字符串放到这个对象里面，并且跟这个对象起了一个名字（binding），名字叫做variable\n",
    "判定：如果没有其他的名字bound到第一个对象，然后这个对象就没有任何referance（引用），所以Python中有一个计数机制（reference count归位0），这样就垃圾桶回收了（garabge collected）~"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python能够让“选择困难症”的小伙伴把最终的决定拖到退后一秒———— Dynamically(动态的)————一直都能变\n",
    "但是并不意味着每一个对象的类型可以随意改变————Strongly typed（强类型）language"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Duck Typing:If it walks like a duck and it quacks like a duck, then it must be a duck\n",
    "如果他装成鸭子的样子，我管他是不是鸭子，我就把它当做鸭子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I am a duck and I am flying(我是一直鸭子，我可以飞哦)\n",
      "I am a Airplane and I can fly(我是一个飞机，我也能飞)\n",
      "I am a irondog and I can fly(我是一只钢铁狗，我能飞！)\n"
     ]
    }
   ],
   "source": [
    "class Duck:\n",
    "    def fly(self):\n",
    "        print(\"I am a duck and I am flying(我是一直鸭子，我可以飞哦)\")\n",
    "\n",
    "class Airplane:\n",
    "    def fly(self):\n",
    "        print(\"I am a Airplane and I can fly(我是一个飞机，我也能飞)\")\n",
    "class Dog:\n",
    "    def fly(self):\n",
    "        print(\"I am a irondog and I can fly(我是一只钢铁狗，我能飞！)\")\n",
    "\n",
    "for thing in Duck(),Airplane(),Dog():\n",
    "    thing.fly()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Quack,Quack~I am a duck!\n",
      "walk, walk ,I am a duck!\n",
      "Quack,Quack ~ I am a person , but I can pretend I am a duck~\n",
      "walk , walk , I am a person, but I can pretend I walk like a duck~\n",
      "This has to be a Duck!\n"
     ]
    }
   ],
   "source": [
    "class Duck:\n",
    "    def quack(self):\n",
    "        print(\"Quack,Quack~I am a duck!\")\n",
    "    def walk(self):\n",
    "        print(\"walk, walk ,I am a duck!\")\n",
    "\n",
    "class Person:\n",
    "    def quack(self):\n",
    "        print(\"Quack,Quack ~ I am a person , but I can pretend I am a duck~\")\n",
    "    def walk(self):\n",
    "        print(\"walk , walk , I am a person, but I can pretend I walk like a duck~\")\n",
    "\n",
    "#Non- duck typing\n",
    "def duck_test(thing):\n",
    "    if isinstance(thing,Duck):\n",
    "        thing.quack()\n",
    "        thing.walk()\n",
    "    else:\n",
    "        thing.quack()\n",
    "        thing.walk()\n",
    "        print(\"This has to be a Duck!\")\n",
    "\n",
    "d=Duck()\n",
    "duck_test(d)\n",
    "\n",
    "p=Person()\n",
    "duck_test(p)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这个时候我们就会发现，我们其实并不在乎这个thing到底是什么class，我们只在乎他能不能quack和walk"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Quack,Quack~I am a duck!\n",
      "walk, walk ,I am a duck!\n",
      "This has to be a Duck!\n"
     ]
    }
   ],
   "source": [
    "# duck typing\n",
    "def duck_test(thing):\n",
    "    thing.quack()\n",
    "    thing.walk()\n",
    "    print(\"This has to be a Duck!\")\n",
    "    \n",
    "duck_test(d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Quack,Quack ~ I am a person , but I can pretend I am a duck~\n",
      "walk , walk , I am a person, but I can pretend I walk like a duck~\n",
      "This has to be a Duck!\n"
     ]
    }
   ],
   "source": [
    "duck_test(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
